﻿using System;
using System.Diagnostics;

namespace Simp.Model
{
	/// <summary>Encapsulates a scope of many expressions resulting into only one.</summary>
	/// <remarks>
	/// <para>This expression is expected to have 2 or more parameters:  a serie of assignations and a return value.</para>
	/// <para>This expression doesn't simplify itself and is meant to be simplified from the outside.</para>
	/// </remarks>
	[ExpressionName("Bound")]
	[DebuggerDisplay("{ExpressionHelper.Serialize(this)}")]
	public class ScopeExpression : IParameterPolicyExpression, IExpressionSerializer
	{
		private readonly IParameterBinding[] _parameterBindings;

		/// <summary>Constructor of a scope.</summary>
		/// <param name="parameterCount"/>
		public ScopeExpression(int parameterCount)
		{
			if (parameterCount < 2)
			{
				throw new ArgumentException(
					"Can't be less than 2:  at least one definition and a return expression",
					"parameterCount");
			}
			_parameterBindings = ExpressionHelper.CreateParameterBinding(parameterCount);
		}

		#region IParameterPolicyExpression Members
		IParameterBinding[] IParameterPolicyExpression.ParameterBindings
		{
			get { return _parameterBindings; }
		}
		#endregion

		#region IExpressionSerializer Members
		void IExpressionSerializer.Serialize(AppendOnlyStringBuilder builder, params IExpression[] parameters)
		{
			if (builder == null)
			{
				throw new ArgumentNullException("builder");
			}
			if (parameters == null)
			{
				throw new ArgumentNullException("parameters");
			}

			builder.Append("(");
			for (int i = 0; i != parameters.Length; ++i)
			{
				IExpression expression = parameters[i];

				ExpressionHelper.Serialize(builder, expression);
				if (i != parameters.Length - 1)
				{
					builder.Append("   ");
				}
			}
			builder.Append(")");
		}
		#endregion
	}
}